import swagger from 'swagger-express-middleware';
import express, { Response } from 'express';
import { desDecrypt, desEncrypt } from './tools';
import { llog } from './logger';

let router;
let middleware: swagger.SwaggerMiddleware;

// 注意：此函数返回的router一定在app.use最早处加载，否则很多解析功能用不上
export let loadSwagger = async function() {
	// 创建一个router用来加载swagger
	router = express.Router({
		caseSensitive: false,
		mergeParams: false,
		strict: false,
	});
	middleware = await new Promise<swagger.SwaggerMiddleware>((fill, reject) => {
		swagger('swagger/swagger.yaml', router, function(err, middleware) {
			if (err) reject(err);
			else fill(middleware);
		});
	});

	// 对加密字段进行解密
	let ecType = 'text/mbec';
	let ecKey = 'xiaoting';
	router.use(require('body-parser').text({ type: ecType }));
	router.use((req: express.Request, res: express.Response, next: express.NextFunction) => {
		let ct = req.headers['content-type'];
		// llog('filter', req.url, ct, req.body, typeof req.body);
		if (ct && ct.indexOf(ecType) >= 0) {
			let ebody = req.body;
			let dbody = desDecrypt(ebody, ecKey);
			llog('decrypt body', req.url, dbody);
			req.body = dbody;

			let send = res.send;
			res.send = function(body): Response {
				if (typeof body != 'string') body = JSON.stringify(body);
				let ebody = desEncrypt(body, ecKey);
				llog('hook the mbec response', body, ebody);
				res.setHeader('content-type', ecType);
				send.call(this, ebody);
				return;
			};
		}
		next();
	});

	// 此插件提供req.swagger，可从中获取参数定义，虽然没直接用处，但是所有其它插件的基础
	router.use(middleware.metadata());
	// 此插件提供req.body等参数解析功能，参数缺失和类型验证也在这里，依赖metadata
	router.use(middleware.parseRequest());
	// 此插件提供请求验证，实际上就是对不存在的路径报个错，依赖metadata
	// 可能产生的报错 [http500, http401, http404, http405, http406, http413, http415];
	router.use(middleware.validateRequest());

	// 此插件提供/api-docs，获取协议描述的json文件,主要是给html界面中使用
	router.use(middleware.files({ apiPath: '/swagger/api' }));

	// 挂一个swagger ui,  注意这里挂的路径都是与index.html里的引用对应的
	router.use('/swagger', express.static('swagger'));
	router.use('/swagger/assets', express.static('node_modules/swagger-ui-dist'));

	// app.use(router);
	return router;
};
